/**
 * WebSocket服务
 * 用于实时监控数据推送
 */

interface WebSocketMessage {
  type: string
  data?: any
  timestamp?: string
  server_id?: string | number
}

interface MonitoringData {
  overview?: any
  host_status?: any[]
  alerts?: any[]
}

type MessageHandler = (data: any) => void

class WebSocketService {
  private ws: WebSocket | null = null
  private url: string
  private token: string
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private reconnectInterval = 3000
  private heartbeatInterval: number | null = null
  private messageHandlers: Map<string, MessageHandler[]> = new Map()
  private isConnecting = false
  private isManualClose = false

  constructor() {
    // WebSocket URL将在connect方法中动态获取
    // 获取认证token
    this.token = localStorage.getItem('token') || ''
  }

  /**
   * 连接WebSocket
   */
  async connect(): Promise<void> {
    return new Promise(async (resolve, reject) => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        resolve()
        return
      }

      if (this.isConnecting) {
        reject(new Error('正在连接中'))
        return
      }

      this.isConnecting = true
      this.isManualClose = false

      try {
        // 使用统一的WebSocket配置工具
        const { getMonitoringWebSocketUrl } = await import('./websocket-config')
        const wsUrl = getMonitoringWebSocketUrl(this.token)
        this.ws = new WebSocket(wsUrl)

        this.ws.onopen = () => {
          console.log('监控WebSocket连接已建立')
          this.isConnecting = false
          this.reconnectAttempts = 0
          this.startHeartbeat()
          resolve()
        }

        this.ws.onmessage = (event) => {
          try {
            const message: WebSocketMessage = JSON.parse(event.data)
            this.handleMessage(message)
          } catch (error) {
            console.error('解析WebSocket消息失败:', error)
          }
        }

        this.ws.onclose = (event) => {
          console.log('监控WebSocket连接已关闭:', event.code, event.reason)
          this.isConnecting = false
          this.stopHeartbeat()

          if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
            this.scheduleReconnect()
          }
        }

        this.ws.onerror = (error) => {
          console.error('监控WebSocket连接错误:', error)
          this.isConnecting = false
          reject(error)
        }

      } catch (error) {
        this.isConnecting = false
        reject(error)
      }
    })
  }

  /**
   * 断开WebSocket连接
   */
  disconnect(): void {
    this.isManualClose = true
    this.stopHeartbeat()

    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
  }

  /**
   * 发送消息
   */
  send(message: WebSocketMessage): void {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message))
    } else {
      console.warn('WebSocket未连接，无法发送消息')
    }
  }

  /**
   * 请求立即更新
   */
  requestUpdate(): void {
    this.send({ type: 'request_update' })
  }

  /**
   * 订阅特定服务器数据
   */
  subscribeServer(serverId: string | number): void {
    this.send({
      type: 'subscribe_server',
      server_id: serverId
    })
  }

  /**
   * 注册消息处理器
   */
  on(messageType: string, handler: MessageHandler): void {
    if (!this.messageHandlers.has(messageType)) {
      this.messageHandlers.set(messageType, [])
    }
    this.messageHandlers.get(messageType)!.push(handler)
  }

  /**
   * 移除消息处理器
   */
  off(messageType: string, handler?: MessageHandler): void {
    if (!this.messageHandlers.has(messageType)) {
      return
    }

    if (handler) {
      const handlers = this.messageHandlers.get(messageType)!
      const index = handlers.indexOf(handler)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    } else {
      this.messageHandlers.delete(messageType)
    }
  }

  /**
   * 处理接收到的消息
   */
  private handleMessage(message: WebSocketMessage): void {
    const { type, data } = message

    // 触发对应类型的处理器
    const handlers = this.messageHandlers.get(type)
    if (handlers) {
      handlers.forEach(handler => {
        try {
          handler(data)
        } catch (error) {
          console.error(`处理${type}消息失败:`, error)
        }
      })
    }

    // 触发通用处理器
    const allHandlers = this.messageHandlers.get('*')
    if (allHandlers) {
      allHandlers.forEach(handler => {
        try {
          handler(message)
        } catch (error) {
          console.error('处理通用消息失败:', error)
        }
      })
    }
  }

  /**
   * 开始心跳检测
   */
  private startHeartbeat(): void {
    this.heartbeatInterval = window.setInterval(() => {
      this.send({ type: 'ping' })
    }, 30000) // 每30秒发送一次心跳
  }

  /**
   * 停止心跳检测
   */
  private stopHeartbeat(): void {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
  }

  /**
   * 安排重连
   */
  private scheduleReconnect(): void {
    this.reconnectAttempts++
    const delay = this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1)

    console.log(`${delay}ms后尝试第${this.reconnectAttempts}次重连...`)

    setTimeout(() => {
      if (!this.isManualClose) {
        this.connect().catch(error => {
          console.error('重连失败:', error)
        })
      }
    }, delay)
  }

  /**
   * 获取连接状态
   */
  get isConnected(): boolean {
    return this.ws !== null && this.ws.readyState === WebSocket.OPEN
  }

  /**
   * 获取连接状态文本
   */
  get connectionState(): string {
    if (!this.ws) return 'disconnected'

    switch (this.ws.readyState) {
      case WebSocket.CONNECTING:
        return 'connecting'
      case WebSocket.OPEN:
        return 'connected'
      case WebSocket.CLOSING:
        return 'closing'
      case WebSocket.CLOSED:
        return 'closed'
      default:
        return 'unknown'
    }
  }
}

// 创建全局WebSocket服务实例
export const monitoringWebSocket = new WebSocketService()

// 导出类型
export type { MessageHandler, MonitoringData, WebSocketMessage }
export default WebSocketService
